package com.example.controller;

import cn.hutool.core.util.StrUtil;
import com.example.annotations.ApiCallAdvice;
import com.example.annotations.RequestLimiter;
import com.example.api.annotations.dict.DictConvert;
import com.example.api.entity.biz.User;
import com.example.api.exception.CommonRuntimeException;
import com.example.api.vo.biz.UserVo;
import com.example.config.redisandlua.AccessLimiter;
import com.example.jwt.util.JwtUtils;
import com.example.service.UserService;
import com.example.util.RedisLock;
import common.annotations.Inner;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import utils.BeanUtils;
import utils.CryptoUtil;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * @Author Story
 * @Date 2022/3/19 23:19
 * @Version 1.0
 */
@RestController
@RequestMapping(value = "/user")
@RequiredArgsConstructor
public class UserController {


    private final UserService userService;

    private final AccessLimiter accessLimiter;

    private final RedisTemplate redisTemplate;

    private final RedisLock redisLock;

    //private final Property property;

    /**
     * 查询 根据主键 id 查询 http://bt.cilise.com/
     *
     * @author zhengkai.blog.csdn.net
     * @date 2022/03/19
     **/
    @RequestMapping("/load")
    @ApiCallAdvice
    public UserVo load(String id) {
        return userService.load(id);
    }

    /**
     * 查询 根据主键 id 查询 http://bt.cilise.com/
     *
     * @author zhengkai.blog.csdn.net
     * @date 2022/03/19
     **/
    @RequestMapping("/getList")
    @ApiCallAdvice
    public List<User> getList(List<String> ids) {
        return userService.getBaseMapper().selectBatchIds(ids);
    }


    /**
     * @author zhengkai.blog.csdn.net
     * @date 2022/03/19
     **/
    @PostMapping("/addUser")
    @SneakyThrows
    public UserVo addUser(@RequestBody UserVo userVo) {
        return userService.addUser(userVo);
    }


    @SneakyThrows
    @GetMapping(value = "/login")
    @Inner
    @ApiCallAdvice
    @RequestLimiter(QPS = 1D, timeout = 1, msg = "玩命加载中,请稍后再试")
    @DictConvert
    public UserVo getLoginToken(@RequestParam("userName") String userName, @RequestParam("password") String password) {
        redisLock.lock(userName, 10000, TimeUnit.SECONDS);
        final User loginUser = userService.login(userName, password);
        UserVo userVo;
        try {
            //给分配一个token 然后返回
            String jwtToken;
            userVo = BeanUtils.toBean(loginUser, UserVo.class);
            jwtToken = JwtUtils.createToken(userVo.getName(), userVo.getMobile(), userVo.getName());
            //进行加密
            userVo.setToken(CryptoUtil.encodeSrc(jwtToken));
        } finally {
            redisLock.unlock(userName);
        }
        return userVo;
    }

    @GetMapping(value = "/username")
    public String checkName(HttpServletRequest req) {
        String name = (String) req.getAttribute("userName");
        return name;
    }

    @GetMapping("test")
    @Inner
    public String test() {
        accessLimiter.limitAccess("ratelimiter-test", 1);
        return "success";
    }

    @GetMapping("getInterfaceCount")
    @ApiCallAdvice
    public Object getInterfaceCount() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        //获取请求的request
        HttpServletRequest request = attributes.getRequest();
        String uri = request.getRequestURI();
        String date = dateFormat("yyyy-MM-dd");
        String ip = getRequestIp(request);

        if (StrUtil.isEmpty(ip)) {
            throw new CommonRuntimeException("IP不能为空");
        }
        // URI+IP+日期 构成以天为维度的key
        String ipKey = uri + "_" + ip + "_" + date;
        Object o = redisTemplate.opsForValue().get(ipKey);
        System.out.println(o);
        return "getInterfaceCount接口访问次数为：" + o;
    }


    private String dateFormat(String pattern) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        return dateFormat.format(new Date());
    }

    public static void main(String[] args) throws InterruptedException {

        for (int i = 0; i < 100; i++) {
            System.out.println("11111111111"+i);
        }
        CompletableFuture.runAsync(()->sync());
    }
    private static void sync(){
        for (int i = 0; i < 100; i++) {
            System.out.println(i);
        }
    }


    /**
     * 获取请求信息
     *
     * @param request
     * @return
     */
    private String getRequestIp(HttpServletRequest request) {
        // 获取请求IP
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip) || "null".equals(ip)) {
            ip = "" + request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip) || "null".equals(ip)) {
            ip = "" + request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip) || "null".equals(ip)) {
            ip = "" + request.getRemoteAddr();
        }
        return ip;
    }
}
